<?php
namespace App\Models\System;

use App\Exceptions\ApiException;
use App\Providers\LengthAwarePaginatorProvider;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Sanctum\HasApiTokens;
use App\Enums\System\SysUser\{UserType, Sex, Status, DelFlag};

/**
* 用户信息表 模型
* @create 2023-08-22 23:19:53
*/
class SysUserModel extends \App\Models\BaseModel {
    use HasFactory, HasApiTokens;

    const Table         = "sys_user";
    const PrimaryKey    = "user_id";
    public $timestamps  = true;

    /** 是否是admin账号 */
    const AdminIds = [1];

    static $Wheres = ['user_id', 'user_type', 'sex', 'status', 'del_flag'];     // 直接定义column, 默认where(column, '=', value)
    public function __construct($attributes = []) {
        parent::__construct($attributes);

        // static::$Wheres['user_id']   = fn($q, $v) => $q->where(atn('user_id'), '=', $v);
        static::$Wheres['user_name']    = fn($q, $v) => $q->where(atn('user_name'), '=', "%{$v}%");
        static::$Wheres['phonenumber']  = fn($q, $v) => $q->where(atn('phonenumber'), '=', "%{$v}%");
        static::$Wheres['begin_time']   = fn($q, $v) => $q->whereDate(atn('create_time'), '>=', $v);    // ymd
        static::$Wheres['end_time']     = fn($q, $v) => $q->whereDate(atn('create_time'), '<=', $v);    // ymd
    }


    public function joinDept() {
        return $this->leftJoin(SysDeptModel::Table, 'user_id', '=', 'user_id');
    }

    /** 部门 */
    public function dept() {
        return $this->hasOne(SysDeptModel::class, 'dept_id', 'dept_id');
    }

    /** 角色 */
    public function roles() {
        return $this->belongsToMany(SysRoleModel::class, 'sys_user_role', 'user_id', 'role_id');
    }

    /** 是否是admin账号 */
    public function isAdmin(): bool {
        return in_array($this->user_id, static::AdminIds);
    }

    public function dataScope($query, ?int $user_id=null): void {
        if ($user_id && in_array($user_id, static::AdminIds)) {
            // 如果是超级管理员，则不过滤数据
        } else {

        }
    }

    /** 记录最近登录ip */
    public function recordLastIp() {
        $this->login_ip = request()->ip();
        $this->login_date = now()->toDateTimeString();
        $this->save();
    }

    /** user bean */
    public function commUser() {
        return collect($this->toArray())->only(static::$Vo)->except(['password']);
    }

    /** ========== 常用查询 ========== */
    static $Vo      = ['user_id','dept_id','user_name','nick_name','email','avatar','phonenumber','password','sex','status','del_flag','login_ip','login_date','create_by','create_time','remark',];
    static $Voi     = ['*', ];
    static $VoDept  = ['dept_id','parent_id','ancestors','dept_name','order_num','leader','status as dept_status',];
    static $VoRole  = ['role_id','role_name','role_key','role_sort','data_scope','status as role_status',];


    public function scopeSelectVo(Builder $query): void {
        // $query->select(atn(static::is_api() ? static::$Voi : static::$Vo, static::Table));
        $query
            ->select(array_merge(atn(static::$Vo), SysDeptModel::atn(static::$VoDept), SysRoleModel::atn(static::$VoRole)))
            ->leftJoin(SysDeptModel::Table, SysDeptModel::atn('dept_id'), '=', atn('dept_id'))
            ->leftJoin(SysUserRoleModel::Table, SysUserRoleModel::atn('user_id'), '=', atn('user_id'))
            ->leftJoin(SysRoleModel::Table, SysRoleModel::atn('role_id'), '=', SysUserRoleModel::atn('role_id'))
            ;
     }

    /** 更新账号登录信息 */
    public function updateLoginInfo($user_id): array {
        $row = static::row_update($user_id, [
            'login_ip'      => request()->ip(),
            'login_date'    => now()->toDateTimeString(),
        ]);
        return ApiException::throw_str($row);
    }

    /** 获取账号&判断状态 */
    public function selectUserByUsername2Status($username, $precallback=null): SysUserModel {
        $user = static::query()->where('user_name', '=', $username)->first();
        if (empty($user)) $msg = "登录用户 $username 不存在";
        else if ($user->del_flag == DelFlag::Del()) $msg = "登录用户 $username 已被删除";
        else if ($user->status == Status::StopUsing()) $msg = "登录用户 $username 已停用";
        if (isset($msg)) {
            $precallback && $precallback($msg);
            ApiException::throw_str($msg);
        }
        return $user;
    }

     /**
     * 根据条件分页查询用户列表
     * 
     * @param $user 用户信息
     * @return 用户信息集合信息 List<SysUserModel>
     */
    public function selectUserList(array $user): Collection {
        $deptid = get_value($user, 'dept_id');
        $rows = $this
                ->select(array_merge(
                    atn(['user_id','dept_id','nick_name','user_name','email','avatar','phonenumber','sex','status','del_flag','login_ip','login_date','create_by','create_time','remark']),
                    SysDeptModel::atn(['dept_name','leader'])
                    ))
                ->leftJoin(SysDeptModel::Table, SysDeptModel::atn('dept_id'), '=', atn('dept_id'))
                ->where(atn('del_flag'), '=', '0')
                ->wheres($user, 'user_id', 'user_name', 'status', 'phonenumber', 'begin_time', 'end_time')
                ->when($deptid, function ($query) use ($deptid) {
                    $query->where(fn($q) => 
                        $q->where(atn('dept_id'), '=', $deptid)
                            ->orWhereRaw(SysUserModel::atn('dept_id') .' in ( select '. SysDeptModel::atn('dept_id') .' from `'. SysDeptModel::Table ."` where find_in_set({$deptid}, `ancestors`))")
                    );
                })
                ->orderByDesc(atn('user_id'))
                ->get()
                ;
        return $rows;
		// <!-- 数据范围过滤 -->
		// ${params.dataScope}
    }

    /**
     * 根据条件分页查询已分配用户角色列表
     * 
     * @param $user 用户信息
     * @return 用户信息集合信息 List<SysUserModel>
     */
    public function selectAllocatedList($user=null): Collection {
        return static::selectVo()
            ->get()
            ;
    }

    /**
     * 根据条件分页查询未分配用户角色列表
     * 
     * @param $user 用户信息
     * @return 用户信息集合信息 List<SysUserModel>
     */
    public function selectUnallocatedList($user): array {
        
    }

    /**
     * 通过用户名查询用户
     * 
     * @param $userName 用户名
     * @return 用户对象信息 SysUserModel
     */
    public function selectUserByUserName($userName): array{

    }

    /**
     * 通过用户ID查询用户
     * 
     * @param $userId 用户ID
     * @return 用户对象信息 SysUserModel
     */
    public function selectUserById($userId): SysUserModel {
        return $this->selectVo()->where(atn(static::PrimaryKey), '=', $userId)->first();
    }

    /**
     * 根据用户ID查询用户所属角色组
     * 
     * @param $userName 用户名
     * @return 结果 String
     */
    public function selectUserRoleGroup($userName): string {

    }

    /**
     * 根据用户ID查询用户所属岗位组
     * 
     * @param $userName 用户名
     * @return 结果 String
     */
    public function selectUserPostGroup($userName): string {

    }

    /**
     * 校验用户名称是否唯一
     * 
     * @param $user 用户信息
     * @return 结果 String
     */
    public function checkUserNameUnique($user): string {

    }

    /**
     * 校验手机号码是否唯一
     *
     * @param $user 用户信息
     * @return 结果 String
     */
    public function checkPhoneUnique($user): string {

    }

    /**
     * 校验email是否唯一
     *
     * @param $user 用户信息
     * @return 结果 String
     */
    public function checkEmailUnique($user): string {

    }

    /**
     * 校验用户是否允许操作
     * 
     * @param $user 用户信息
     */
    public function checkUserAllowed($user): void{

    }

    /**
     * 校验用户是否有数据权限
     * 
     * @param $userId 用户id
     */
    public function checkUserDataScope($userId): void{

    }

    /**
     * 新增用户信息
     * 
     * @param $user 用户信息
     * @return 结果 SysUserModel
     */
    public function insertUser($user): array {

    }

    /**
     * 注册用户信息
     * 
     * @param $user 用户信息
     * @return 结果 SysUserModel
     */
    public function registerUser($user): array {

    }

    /**
     * 修改用户信息
     * 
     * @param $user 用户信息
     * @return 结果 SysUserModel
     */
    public function updateUser($user): array {

    }
    
    /**
     * 用户授权角色
     * 
     * @param $userId 用户ID
     * @param $roleIds 角色组
     */
    public function insertUserAuth($userId, array $roleIds): void{

    }

    /**
     * 修改用户状态
     * 
     * @param $user 用户信息
     * @return 结果 SysUserModel
     */
    public function updateUserStatus($user): array{

    }

    /**
     * 修改用户基本信息
     * 
     * @param $user 用户信息
     * @return 结果 SysUserModel
     */
    public function updateUserProfile($user): array{

    }

    /**
     * 修改用户头像
     * 
     * @param $userName 用户名
     * @param $avatar 头像地址
     * @return 结果 array
     */
    public function updateUserAvatar($userName, $avatar): array{

    }

    /**
     * 重置用户密码
     * 
     * @param $user 用户信息
     * @return 结果 SysUserModel
     */
    public function resetPwd($user): array{

    }

    /**
     * 重置用户密码
     * 
     * @param $userName 用户名
     * @param $password 密码
     * @return 结果 SysUserModel
     */
    public function resetUserPwd($userName, $password): array{

    }

    /**
     * 通过用户ID删除用户
     * 
     * @param $userId 用户ID
     * @return 结果 SysUserModel
     */
    public function deleteUserById($userId): array {

    }
    /**
     * 批量删除用户信息
     * 
     * @param $userIds 需要删除的用户ID
     * @return 结果
     */
    public function deleteUserByIds(array $userIds): array {

    }

    /**
     * 导入用户数据
     * 
     * @param $userList 用户数据列表
     * @param $isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param $operName 操作用户
     * @return 结果 String
     */
    public function importUser(array $userList, bool $isUpdateSupport, $operName): string {

    }

    /** 根据UserId获取 */
    public function selectByUserId($user_id): SysUserModel {
        $where = [['user_id', '=', "{$user_id}"]];
        return throw_str(
            static::row($where) ?? "数据($user_id)为空~"
        );
    }


    /** 获取列表 @return SysUser[]+paginator() */
    public function selectList(int|array $pag=1, array $param=[]): LengthAwarePaginatorProvider {
        return static::rows_pag($pag, [], fn($q)=>$q
                    // ->when(isset($param['user_id']), fn($q)=>$q->where('user_id', '=', $param['user_id']))
                    ->wheres($param, 'user_id','user_type','sex','status','del_flag')
                    ->orderByDesc("user_id")
        );
    }


    /** 插入数据 */
    public function insertData(array $data): SysUserModel {
        return throw_str(
            static::row_add([
                // 'user_id'            => $data['user_id'],
                'dept_id'               => $data['dept_id'] ?? '',
                'user_name'             => $data['user_name'],
                'nick_name'             => $data['nick_name'],
                'user_type'             => $data['user_type'] ?? '00',
                'email'                 => $data['email'] ?? '',
                'phonenumber'           => $data['phonenumber'] ?? '',
                'sex'                   => $data['sex'] ?? '0',
                'avatar'                => $data['avatar'] ?? '',
                'password'              => $data['password'] ?? '',
                'status'                => $data['status'] ?? '0',
                'del_flag'              => $data['del_flag'] ?? '0',
                'login_ip'              => $data['login_ip'] ?? '',
                'login_date'            => $data['login_date'] ?? '',
                'create_by'             => $data['create_by'] ?? '',
                // 'create_time'        => $data['create_time'] ?? '',
                'update_by'             => $data['update_by'] ?? '',
                // 'update_time'        => $data['update_time'] ?? '',
                'remark'                => $data['remark'] ?? '',
            ])
        );
    }


    /** 更新数据 */
    public function updateData(int|array $idOrWhere, array $data): SysUserModel {
        $values = static::when(
                    $data, 
                    // 'user_id',
                    'dept_id',
                    'user_name',
                    'nick_name',
                    'user_type',
                    'email',
                    'phonenumber',
                    'sex',
                    'avatar',
                    'password',
                    'status',
                    'del_flag',
                    'login_ip',
                    'login_date',
                    'create_by',
                    // 'create_time',
                    'update_by',
                    // 'update_time',
                    'remark',
                );
        return throw_str(
            static::row_update($idOrWhere, $values)
        );
    }


    /** 删除数据 */
    public function deleteData(int|array $idOrWhere): SysUserModel {
        return throw_str(
            static::row_delete($idOrWhere)
        );
    }



}